// hashchange popstate
import { reroute } from './reroute.js'
import { isInBrowser } from '../utils/runtime-environment'
import { isStarted } from '../start'

export const routingEventsListeningTo = ['hashchange', 'popstate']

const captureEventisteners = {
  hashchange: [],
  popstate: []
}

export function navigateToUrl (obj) {
  let url
  if (typeof obj === 'string') {
    url = obj
  } else if (this && this.href) {
    url = this.href
  } else if (
    obj &&
    obj.currentTarget &&
    obj.currentTarget.href &&
    obj.preventDefault
  ) {
    url = obj.currentTarget.href
    obj.preventDefault()
  }
  const current = parseUri(window.location.href)
  const destination = parseUri(url)

  if (url.indexOf('#') > -1) {
    window.location.hash = destination.hash
  } else if (current.host !== destination.host && destination.host) {
    window.location.href = url
  } else if (
    destination.pathname === current.pathname &&
    destination.search === current.search
  ) {
    window.location.hash = destination.hash
  } else {
    window.history.pushState(null, null, url)
  }
}

export function callCapturedEventListeners (eventName) {
  if (eventArguments) {

  }
}

function urlReroute() {
  reroute([], arguments) // 会根据路径加载不同的应用
}

function patchedUpdateState(updateState, methodName) {
  return function() {
    const urlBefore = window.location.href
    const result = updateState.apply(this, arguments) // 调用切换方法
    const urlAfter = window.location.href
    if (urlBefore !== urlAfter) {
      if (isStarted()) {
        window.dispatchEvent(
          createPopStateEvent(window.history.state, methodName)
        )
      } else {
        reroute([])
      }
    }
    return result
  }
}

function createPopStateEvent (state, originalMethodName) {
  let evt
  try {
    evt = new PopStateEvent('popstate', { state })
  } catch (err) {
    evt = document.createEvent("PopStateEvent");
    evt.initPopStateEvent("popstate", false, false, state)
  }
  evt.singleSpa = true
  evt.singleSpaTrigger = originalMethodName
  return evt
}

if (isInBrowser) {
  window.addEventListener('hashchange', urlReroute)
  window.addEventListener('popstate', urlReroute)
  
  const originalAddEventListener = window.addEventListener
  const originalRemoveEventListener = window.removeEventListener
  
  window.addEventListener = function(eventName, fn) {
    if (typeof fn === 'function') {
      if (
        routingEventsListeningTo.indexOf(eventName) > -1 && 
        !captureEventisteners[eventName].some(listener => listener === fn)
      ) {
        captureEventisteners[eventName].push(fn)
        return
      }
    }
    return originalAddEventListener.apply(this, arguments)
  }
  window.removeEventListener = function(eventName, listenerFn) {
    if (typeof listenerFn === 'function') {
      if (routingEventsListeningTo.indexOf(eventName) > -1) {
        captureEventisteners[eventName] = captureEventisteners[eventName].filter(fn => fn !== listenerFn)
        return
      }
    }
    return originalRemoveEventListener.apply(this, arguments)
  }

  window.history.pushstate = patchedUpdateState(window.history.pushstate, 'pushstate')
  window.history.replacestate = patchedUpdateState(window.history.replacestate, 'replacestate')

  if (!window.singleSpaNavigate) {
    window.singleSpaNavigate = navigateToUrl
  }
}

function parseUri (str) {
  const anchor = document.createElement('a')
  anchor.href = str
  return anchor
}

// 用户可能还会绑定自己的路由事件
// 当我们应用切换后，还需要执行原来的方法，需要在应用切换后继续执行